def unittest() {
    timeout(40) {
        sh 'mvn -U -Dmaven.test.failure.ignore clean compile test'
    }
}

def report() {
    junit '**/target/surefire-reports/TEST-*.xml'
    jacoco execPattern: '**/target/**.exec', classPattern: '**/target/classes', sourcePattern: '**/src/main/java'
}

def compile() {
    sh 'mvn clean compile'
}

def sonar(branchs = ['master']) {
    timeout(120) {
        sh 'mvn sonar:sonar -Dsonar.host.url=http://sonar-tx.http.svc.pre.ali.im30 -Dsonar.login=27023b0400857c5d5ae67f312fcd154006a020ce'
//        String branch = jobUtil.getBranchName()
//        if (branchs.contains(branch)) {
//            sh 'mvn sonar:sonar -Dsonar.host.url=http://sonar-tx.http.svc.pre.ali.im30 -Dsonar.login=27023b0400857c5d5ae67f312fcd154006a020ce'
//        }
    }
}

/**
 * 进行 pmd 代码检测，如果有检测结果，则上报结果
 *
 * @param branchs
 * @return
 */
def pmd(branchs = 'master') {
    if (branchs.contains(env.BRANCH_NAME)) {
        sh 'mvn compile pmd:pmd -Djava.version=1.8'
        def pmdFilePath = "**/target/pmd.xml"
        // 记录 pmd 结果至构建信息中
        recordIssues enabledForFailure: true, tool: pmdParser(pattern: "${pmdFilePath}")
        // 上报 pmd 结果
        def exitCode = sh script: "ls ${pmdFilePath}", returnStatus: true
        boolean exists = exitCode == 0
        if (exists) {
            def highLevel = '1|2'
            def normalLevel = '3|4|5'
            def highCounts = sh script: "cat ${pmdFilePath} " +
                    "| grep '<violation' | grep 'priority=\\\"[${highLevel}]\\\"' " +
                    "| wc -l  | sed -e 's/[ |\\n]//g'", returnStdout: true
            def normalCounts = sh script: "cat ${pmdFilePath} " +
                    "| grep '<violation' | grep 'priority=\\\"[${normalLevel}]\\\"' " +
                    "| wc -l  | sed -e 's/[ |\\n]//g'", returnStdout: true
            echo "highCounts: ${highCounts}"
            echo "normalCounts: ${normalCounts}"
            def timestamp = System.currentTimeMillis()
            def projectName = getProjectName()
            def submitData = """
{
  "reportTime": ${timestamp},
  "reportFrom": "Java CI",
  "type": "javapmd",
  "reportData": [
    {
      "server": "${projectName}",
      "pmdUrl": "${BUILD_URL}/pmd",
      "data": [
        {
          "name": "highCount",
          "value": "${highCounts}",
          "descripition": "PMD 检测代码规范问题数（优先级：High）",
          "type": "number"
        },
        {
          "name": "normalCount",
          "value": "${normalCounts}",
          "descripition": "PMD 检测代码规范问题数（优先级：Normal）",
          "type": "number"
        }
      ]
    }
  ]
}
""".replaceAll("\n", "")
            def submitResult = sh script: "curl -X POST  -H 'Content-Type: application/json;charset=UTF-8' " +
                    "-d '${submitData}' " +
                    "'http://quality-data.http.svc.ali.im30/quality/data/submit'", returnStdout: true
            echo submitResult
        }
    }
}

def dependencies(branchs = ['master']) {
    timeout(40) {
        String branch = jobUtil.getBranchName()
        if (branchs.contains(branch)) {
            try {
                String url = sh(returnStdout: true, script: "git config remote.origin.url").trim().toString()
                url = URLEncoder.encode(url, "UTF-8")
                def script = "mvn compile com.im30.maven:im30-maven-plugin:0.1.2:version-scan -Dall=true -Dmaven.test.skip=true -Dserver=http://172.30.11.215:8080/api/webhook/dependencies?build=${env.BUILD_NUMBER}\\&job=${env.JOB_NAME}\\&url=${url}".toString()
                echo script
                sh script
            } catch (e) {
                echo e.message
            }
        }
    }
}

def snapshotCheck(branch) {
    if ('master' != branch) {
        return ''
    }
    String output = ''
    timeout(10) {
        try {
            sh 'mvn org.apache.maven.plugins:maven-enforcer-plugin:3.0.0:enforce -Drules=requireReleaseDeps --log-file snapshot-check.log'
        } catch (e) {
            output = sh(returnStdout: true, script: "cat snapshot-check.log | grep -v '\\['").trim().toString()
            String url = "https://open.feishu.cn/open-apis/bot/v2/hook/112510b3-9588-4935-826d-43508eb60442"
            echo output
            notifyUtil.notifyText(url, "SNAPSHOT 检测不通过", "${env.BUILD_URL}\\n${output}")
        }
    }
    return output
}

/**
 * 处理 Phab 项目的 Maven 发布
 *
 * @param buildConfig
 * @return
 */
def deployMaven(buildConfig = null) {
    if (buildConfig == null) {
        return
    }

    if (buildConfig.isAppRepo() && buildConfig.getLibs() == null) {
        // 如果是 app 类型且未声明要构建的 libs，则返回
        return
    }

    // 获取 build.yml 中配置的当前分支的 suffix，如未配置则用默认值
    def suffix = buildConfig.getSuffix(env.BRANCH_NAME)
    if (suffix == null) {
        return
    }

    try {
        def (nextVersion, snapshotTagExisted) = getNextVersion(suffix)
        if (nextVersion == null) {
            return
        }

        currentBuild.displayName = currentBuild.displayName + '(' + nextVersion + ")"
        sshagent(credentials: ['im30']) {
            tagVersion(nextVersion, snapshotTagExisted)
            doDeploy(nextVersion, buildConfig)
        }
    } catch (err) {
        echo "Deploy maven failed!"
        echo err.getMessage()
    }
}

/**
 * 处理 GitLab 中的 maven 发布
 *
 * @param buildConfig
 * @return
 */
def deployMavenInGitLab(buildConfig = null) {
    if (buildConfig == null) {
        return
    }
    if (buildConfig.isAppRepo() && buildConfig.getLibs() == null) {
        // 如果是 app 类型且未声明要构建的 libs，则返回
        return
    }

    // 获取 build.yml 中配置的当前分支的 suffix，如未配置则用默认值
    def suffix = buildConfig.getGitLabSuffix(env.gitlabBranch)
    def isFeatureBranch = (suffix == null)

    try {
        def nextVersion = null
        def snapshotTagExisted = false
        if (isFeatureBranch) {
            // 默认打包，如果在配置中关闭，则直接返回，也不会打 tag
            if (buildConfig.disableFeatureBranchDeploy()) {
                return
            }
            // 如果 suffix 为空，则说明是未进行配置的功能分支
            nextVersion = generateFeatureBranchVersion(env.gitlabBranch)
            echo "Current feature deploy version: " + nextVersion
        } else {
            (nextVersion, snapshotTagExisted) = getNextVersion(suffix)
            if (nextVersion == null) {
                return
            }
        }

        currentBuild.displayName = currentBuild.displayName + '(' + nextVersion + ")"
        sshagent(credentials: ['gitlab-deploy-key']) {
            if (!isFeatureBranch || buildConfig.enableFeatureBranchTag()) {
                // 两种情况打 tag：1. 不是功能分支 2. 是功能分支且开启了打 tag 的配置
                tagVersion(nextVersion, snapshotTagExisted)
            }
            doDeploy(nextVersion, buildConfig)
        }
    } catch (err) {
        echo "Deploy maven failed!"
        echo err.getMessage()
    }
}

/**
 * 获取功能分支的版本号：分支名 + timestamp（秒级）
 *
 * @param branchName
 * @return
 */
def generateFeatureBranchVersion(String branchName) {
    def timestamp = (long) (System.currentTimeMillis() / 1000)
    return branchName + "-" + timestamp
}

/**
 * 对版本的版本号的末位进行递增
 * 如果存在 SNAPSHOT，则不递增
 *
 * @param suffix
 * @return
 */
def getNextVersion(String suffix) {
    // 获取项目中配置的 version 和 revision，version 需要在后续跟上配置中的 suffix
    def currentVersion = versionUtil.getVersion() + suffix
    def revision = versionUtil.getRevision()

    // 获取 revision 后缀，兼容带着后缀的 revision
    def revisionSuffix = versionUtil.getSuffix(revision)
    revision = versionUtil.removeSuffix(revision)
    // 获取版本后缀，兼容带着后缀的版本号
    def versionSuffix = versionUtil.getSuffix(currentVersion)
    currentVersion = versionUtil.removeSuffix(currentVersion)

    if (versionUtil.isPropertyEmpty(currentVersion) || versionUtil.isPropertyEmpty(revision)) {
        sh 'echo "Do not support revision deploy, return."'
        return null
    }

    // 通过 tag 获取需要发布的版本号
    def (nextRevision, snapshotTagExisted) = versionUtil.getNextVersionByTag(currentVersion, revision, versionSuffix)
    nextRevision = nextRevision + revisionSuffix
    // 通过 revision 获取新的 version，需要在后续跟上配置中的 suffix
    String nextVersion = versionUtil.getVersionByRevision(nextRevision)
    if (!nextVersion.endsWith(suffix)) {
        nextVersion += suffix
    }
    if (versionUtil.isPropertyEmpty(nextVersion)) {
        sh 'echo "Get next version from tag failed, return."'
        return null
    }

    return [nextVersion, snapshotTagExisted]
}

/**
 * 为当前发布打上 tag
 *
 * @param version
 * @param snapshotTagExisted
 * @return
 */
def tagVersion(version, snapshotTagExisted = false) {
    def tagName = "v${version}"

    sh "git config --global user.name 'jenkins'"
    sh "git config --global user.email 'jenkins@im30.com'"

    if (snapshotTagExisted) {
        // 如果存在重复的 snapshot tag，则删除之前的 tag
        sh "git tag -d ${tagName}"
        sh "git push origin :refs/tags/${tagName}"
    }

    sh "git tag -a -m '[jenkins pipeline] release for ${tagName}' ${tagName}"
    sh "git push origin ${tagName}"
}

def doDeploy(revision, buildConfig) {
    def deployCmd = "mvn clean deploy -Dproject.build.sourceEncoding=UTF-8 -Dproject.reporting.outputEncoding=UTF-8 --batch-mode -Dmaven.test.skip=true -Drevision=${revision} -am"
    def libs = buildConfig.getLibs()
    if (libs != null) {
        deployCmd += " -pl ${libs}"
    }
    sh "${deployCmd}"
}

/**
 * 获取项目名
 */
def getProjectName() {
    def projectName = sh script: "mvn help:evaluate -Dexpression=project.name  |  grep -v '\\[' | grep -v 'Download'", returnStdout: true
    return projectName.trim()
}